package ma.ensao.evalmetrics.util.javaProjects;

import java.awt.Color;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import ma.ensao.evalmetrics.controller.CaracteristiquesManager;
import ma.ensao.evalmetrics.controller.ClasseManager;
import ma.ensao.evalmetrics.controller.FileManager;
import ma.ensao.evalmetrics.controller.MethodManager;
import ma.ensao.evalmetrics.controller.MetriquesManager;
import ma.ensao.evalmetrics.controller.ProprieteManager;
import ma.ensao.evalmetrics.controller.ResultManager;
import ma.ensao.evalmetrics.controller.StatManager;
import ma.ensao.evalmetrics.controller.SubcaracManager;
import ma.ensao.evalmetrics.controller.rapportManager;
import ma.ensao.evalmetrics.controller.metrics.Calcule;
import ma.ensao.evalmetrics.controller.metrics.POFManager;
import ma.ensao.evalmetrics.controller.metrics.QDoxTester;
import ma.ensao.evalmetrics.model.Caracteristiques;
import ma.ensao.evalmetrics.model.Metriques;
import ma.ensao.evalmetrics.model.MyFile;
import ma.ensao.evalmetrics.model.Propriete;
import ma.ensao.evalmetrics.model.Result;
import ma.ensao.evalmetrics.model.ResultClasse;
import ma.ensao.evalmetrics.model.ResultMethod;
import ma.ensao.evalmetrics.model.Stat;
import ma.ensao.evalmetrics.model.Subcarac;
import ma.ensao.evalmetrics.model.rapport;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.time.Second;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;

import com.opensymphony.xwork2.ActionSupport;
//Class d'action
@SuppressWarnings("serial")
public class action extends ActionSupport {
	private Calcule calcule = new Calcule();
	private Metriques metric;
	private MetriquesManager metriquesmanager = new MetriquesManager();
	private ProprieteManager proprietemanager = new ProprieteManager();
	private CaracteristiquesManager caracteristiques = new CaracteristiquesManager();
	private SubcaracManager subcarac = new SubcaracManager();
	private JFreeChart chart;

	private MyFile myFile;
	private POFManager manager;
	private QDoxTester qdox;
	private ArrayList<ArbProjectStructure> packages;

	private rapport report;
	private rapportManager reportmanager;
	private Long id;
	private FileManager projet;

	private Metriques parametres;
	private Caracteristiques carac;
	private Subcarac sub;
	private Propriete propriete;

	private Result result;
	private Stat stat;
	private List<ResultMethod> resultMethods;
	private List<ResultClasse> resultClasses;

	public List<ResultClasse> getResultClasses() {
		return resultClasses;
	}

	public void setResultClasses(List<ResultClasse> resultClasses) {
		this.resultClasses = resultClasses;
	}

	public List<ResultMethod> getResultMethods() {
		return resultMethods;
	}

	public void setResultMethods(List<ResultMethod> resultMethods) {
		this.resultMethods = resultMethods;
	}

	public Result getResult() {
		
		return result;
	}

	public void setResult(Result result) {
		this.result = result;
	}

	public ResultManager getResultmanager() {
		return resultmanager;
	}

	public void setResultmanager(ResultManager resultmanager) {
		this.resultmanager = resultmanager;
	}

	private ResultManager resultmanager;
	private StatManager statmanager;
	MethodManager methodmanager;
	ClasseManager classmanager;

	private double metric_fonct;
	private double metric_fiab;
	private double metric_util;
	private double metric_effic;
	private double metric_maint;
	private double metric_port;

	public QDoxTester getQdox() {
		return qdox;
	}

	public void setQdox(QDoxTester qdox) {
		this.qdox = qdox;
	}

	public ArrayList<ArbProjectStructure> getPackages() {
		return packages;
	}

	public void setPackages(ArrayList<ArbProjectStructure> packages) {
		this.packages = packages;
	}

	private String monjava;

	public action() {
		manager = new POFManager();
		qdox = new QDoxTester();
		projet = new FileManager();
	}

	public String execute() {
		return SUCCESS;
	}

	public String folder() {
		System.out.println(myFile.getFolder());
		// manager.read(myFile.getFolder());

		return SUCCESS;

	}

	public String listejava() throws FileNotFoundException, IOException {
		report = new rapport();
		reportmanager = new rapportManager();
		report = reportmanager.calculeRapport(report, getId());
		System.out.println("--id" + getId());
		myFile = projet.testerprojet(getId());
		System.out.println("+" + myFile.getFolder());
		qdox.action(new File(myFile.getFolder()));
		int size = qdox.getpathjava().size();
		System.out.println("size" + size);
		packages = new ArrayList<ArbProjectStructure>(size);

		List<String> pathjava = qdox.getpathjava();
		for (int k = 0; k < pathjava.size(); k++) {
			ArbProjectStructure pathPack = new ArbProjectStructure();
			JavaClasses JC = new JavaClasses(new File(pathjava.get(k)));
			JC.packagesNames();

			pathPack.setPackName(JC.getClassesPackage().getName());// package
																	// name
			pathPack.setPackPath(pathjava.get(k).substring(0,
					pathjava.get(k).lastIndexOf('\\') + 1));// pack path
			pathPack.setJavaName(pathjava.get(k)
					.substring(pathjava.get(k).lastIndexOf('\\') + 1).trim());// javaName
			pathPack.setJavaPath(pathjava.get(k));// java path
			packages.add(pathPack);
			System.out.println("000java:"
					+ pathjava.get(k)
							.substring(pathjava.get(k).lastIndexOf('\\') + 1)
							.trim());
		}
		for (int k = 0; k < pathjava.size(); k++) {
			System.out.println("++pack:" + packages.get(k).getJavaName());
		}
		
		rangePackages();

		return SUCCESS;
	}
	
	public String graphe_carac() {
		qdox = new QDoxTester();
		myFile = projet.testerprojet(getId());
		System.out.println("essaye" + myFile.getFolder());
		qdox.actionarbo(new File(myFile.getFolder()));
		qdox.metric(getId());

		setParametres(qdox.getParametres());
		setCarac(qdox.getCarac());
		setSub(qdox.getSub());
		setResult(qdox.getResult());
		setStat(qdox.getStat());
		setResultMethods(qdox.getResultMethods());
		setResultClasses(qdox.getResultClasses());
		setPropriete(qdox.getPropriete());

		resultmanager = new ResultManager();
		statmanager = new StatManager();
		methodmanager =new MethodManager();
		classmanager = new ClasseManager();

		result.setIdProjet(getId());
		stat.setIdProjet(getId());
		int testId = methodmanager.testValue(getId());
		int testIdClass = classmanager.testId(getId());
		for(int i=0;i<resultMethods.size();i++){
			resultMethods.get(i).setIdProjet(getId());
			resultMethods.get(i).setIdtest(testId);
		}

		for(int i=0;i<resultClasses.size();i++){
			resultClasses.get(i).setIdProjet(getId());
			resultClasses.get(i).setIdtest(testIdClass);
		}

		resultmanager.add(result);
		statmanager.add(stat);
		if(resultMethods.size()>0){
		methodmanager.add(resultMethods);
		}
		if(resultClasses.size()>0){
		classmanager.addAll(resultClasses);
		}
		metric_fonct = carac.getFonctionnalite();
		metric_fiab = carac.getReliabilite();
		metric_util = carac.getUsabilite();
		metric_effic = carac.getEfficacite();
		metric_maint = carac.getMaintenabilite();
		metric_port = carac.getPortabilite();

		// mymetriques=qdox.getMymetriques();

		System.out.println("iiiiiid" + getId());
		File file = new File("list.txt");
		file.delete();
		FileWriter fw;
		try {
			fw = new FileWriter("list.txt", true);
			BufferedWriter bw = new BufferedWriter(fw);
			PrintWriter pw = new PrintWriter(bw);
			pw.print(getId());
			bw.newLine();
			pw.close();
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

		List<Result> liste = resultmanager.MesResultat(id);
		TimeSeries pop1 = new TimeSeries("Fonctionnalité", Second.class);
		TimeSeries pop2 = new TimeSeries("Fiabilité", Second.class);
		TimeSeries pop3 = new TimeSeries("Utilisabilité", Second.class);
		TimeSeries pop4 = new TimeSeries("Efficacité", Second.class);
		TimeSeries pop5 = new TimeSeries("Maintenabilité", Second.class);
		TimeSeries pop6 = new TimeSeries("Portabilité", Second.class);

		for (int i = 1; i <= liste.size(); i++) {
			result = liste.get(i - 1);
			System.out.println(result.getLOC());
			long ts = result.getDate().getTime();
			Calendar cal = Calendar.getInstance();
			cal.setTimeInMillis(ts);
			int year = cal.get(Calendar.YEAR);
			int day = cal.get(Calendar.DAY_OF_MONTH);
			int month = cal.get(Calendar.MONTH) + 1;

			parametres = metriquesmanager.list(id).get(0);
			parametres = calcule.calculMetrique(parametres, result);
			propriete = proprietemanager.list(id).get(0);
			propriete = calcule.calculPropriete(propriete);
			sub = subcarac.list(id).get(0);
			sub = calcule.calculSubcarac(sub);
			carac = caracteristiques.list(id).get(0);
			carac = calcule.calculCaracteristiques(carac);

			pop1.add(new Second(result.getDate().getSeconds(), result.getDate()
					.getMinutes(), result.getDate().getHours(), day, month,
					year), carac.getFonctionnalite());
			pop2.add(new Second(result.getDate().getSeconds(), result.getDate()
					.getMinutes(), result.getDate().getHours(), day, month,
					year), carac.getReliabilite());
			pop3.add(new Second(result.getDate().getSeconds(), result.getDate()
					.getMinutes(), result.getDate().getHours(), day, month,
					year), carac.getUsabilite());
			pop4.add(new Second(result.getDate().getSeconds(), result.getDate()
					.getMinutes(), result.getDate().getHours(), day, month,
					year), carac.getEfficacite());
			pop5.add(new Second(result.getDate().getSeconds(), result.getDate()
					.getMinutes(), result.getDate().getHours(), day, month,
					year), carac.getMaintenabilite());
			pop6.add(new Second(result.getDate().getSeconds(), result.getDate()
					.getMinutes(), result.getDate().getHours(), day, month,
					year), carac.getPortabilite());

		}

		TimeSeriesCollection dataset = new TimeSeriesCollection();
		dataset.setDomainIsPointsInTime(true);

		dataset.addSeries(pop1);
		dataset.addSeries(pop2);
		dataset.addSeries(pop3);
		dataset.addSeries(pop4);
		dataset.addSeries(pop5);
		dataset.addSeries(pop6);

		chart = ChartFactory.createTimeSeriesChart("Caractéristiques", "Date",
				"Valeur", dataset, true, true, false);
		XYPlot plot = chart.getXYPlot();
		DateAxis axis = (DateAxis) plot.getDomainAxis();
		plot.setBackgroundPaint(new Color(0xffffe0));
		plot.setDomainGridlinesVisible(true);
		plot.setDomainGridlinePaint(Color.lightGray);
		plot.setRangeGridlinesVisible(true);
		plot.setRangeGridlinePaint(Color.lightGray);
		plot.setDomainCrosshairVisible(true);
		plot.setRangeCrosshairVisible(false);
		final XYItemRenderer xyitemrenderer = plot.getRenderer();
		if (xyitemrenderer instanceof XYLineAndShapeRenderer) {
			final XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) xyitemrenderer;
			renderer.setBaseShapesFilled(true);
			renderer.setBaseShapesVisible(true);
			renderer.setShapesVisible(true);
			renderer.setDrawOutlines(true);
		}
		axis.setDateFormatOverride(new SimpleDateFormat("dd-MM-yy '\n' HH:mm"));

		System.err.println("fin chart");


		return SUCCESS;
	}

	public String Arbo() {
		qdox = new QDoxTester();
		myFile = projet.testerprojet(getId());
		System.out.println("essaye" + myFile.getFolder());
		qdox.actionarbo(new File(myFile.getFolder()));
		qdox.metric(getId());

		setParametres(qdox.getParametres());
		setCarac(qdox.getCarac());
		setSub(qdox.getSub());
		setResult(qdox.getResult());
		setStat(qdox.getStat());
		setPropriete(qdox.getPropriete());
		setResultMethods(qdox.getResultMethods());
		setResultClasses(qdox.getResultClasses());

		resultmanager = new ResultManager();
		statmanager = new StatManager();
		methodmanager =new MethodManager();
		classmanager = new ClasseManager();

		result.setIdProjet(getId());
		stat.setIdProjet(getId());
		int testId = methodmanager.testValue(getId())+1;
		int testIdClass = classmanager.testId(getId())+1;
		for(int i=0;i<resultMethods.size();i++){
			resultMethods.get(i).setIdProjet(getId());
			resultMethods.get(i).setIdtest(testId);
		}

		for(int i=0;i<resultClasses.size();i++){
			resultClasses.get(i).setIdProjet(getId());
			resultClasses.get(i).setIdtest(testIdClass);
			
		}
		if(resultMethods.size()>0){
		methodmanager.add(resultMethods);
		}
		if(resultClasses.size()>0){
		classmanager.addAll(resultClasses);
		}
		resultmanager.add(result);
		statmanager.add(stat);
		metric_fonct = carac.getFonctionnalite();
		metric_fiab = carac.getReliabilite();
		metric_util = carac.getUsabilite();
		metric_effic = carac.getEfficacite();
		metric_maint = carac.getMaintenabilite();
		metric_port = carac.getPortabilite();

		// mymetriques=qdox.getMymetriques();

		System.out.println("iiiiiid" + getId());
		File file = new File("list.txt");
		file.delete();
		FileWriter fw;
		try {
			fw = new FileWriter("list.txt", true);
			BufferedWriter bw = new BufferedWriter(fw);
			PrintWriter pw = new PrintWriter(bw);
			pw.print(getId());
			bw.newLine();
			pw.close();
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

		List<Result> liste = resultmanager.MesResultat(id);
		TimeSeries pop1 = new TimeSeries("Fonctionnalité", Second.class);
		TimeSeries pop2 = new TimeSeries("Fiabilité", Second.class);
		TimeSeries pop3 = new TimeSeries("Utilisabilité", Second.class);
		TimeSeries pop4 = new TimeSeries("Efficacité", Second.class);
		TimeSeries pop5 = new TimeSeries("Maintenabilité", Second.class);
		TimeSeries pop6 = new TimeSeries("Portabilité", Second.class);

		for (int i = 1; i <= liste.size(); i++) {
			result = liste.get(i - 1);
			System.out.println(result.getLOC());
			long ts = result.getDate().getTime();
			Calendar cal = Calendar.getInstance();
			cal.setTimeInMillis(ts);
			int year = cal.get(Calendar.YEAR);
			int day = cal.get(Calendar.DAY_OF_MONTH);
			int month = cal.get(Calendar.MONTH) + 1;

			parametres = metriquesmanager.list(id).get(0);
			parametres = calcule.calculMetrique(parametres, result);
			propriete = proprietemanager.list(id).get(0);
			propriete = calcule.calculPropriete(propriete);
			sub = subcarac.list(id).get(0);
			sub = calcule.calculSubcarac(sub);
			carac = caracteristiques.list(id).get(0);
			carac = calcule.calculCaracteristiques(carac);

			pop1.add(new Second(result.getDate().getSeconds(), result.getDate()
					.getMinutes(), result.getDate().getHours(), day, month,
					year), carac.getFonctionnalite());
			pop2.add(new Second(result.getDate().getSeconds(), result.getDate()
					.getMinutes(), result.getDate().getHours(), day, month,
					year), carac.getReliabilite());
			pop3.add(new Second(result.getDate().getSeconds(), result.getDate()
					.getMinutes(), result.getDate().getHours(), day, month,
					year), carac.getUsabilite());
			pop4.add(new Second(result.getDate().getSeconds(), result.getDate()
					.getMinutes(), result.getDate().getHours(), day, month,
					year), carac.getEfficacite());
			pop5.add(new Second(result.getDate().getSeconds(), result.getDate()
					.getMinutes(), result.getDate().getHours(), day, month,
					year), carac.getMaintenabilite());
			pop6.add(new Second(result.getDate().getSeconds(), result.getDate()
					.getMinutes(), result.getDate().getHours(), day, month,
					year), carac.getPortabilite());

		}

		TimeSeriesCollection dataset = new TimeSeriesCollection();
		dataset.setDomainIsPointsInTime(true);

		dataset.addSeries(pop1);
		dataset.addSeries(pop2);
		dataset.addSeries(pop3);
		dataset.addSeries(pop4);
		dataset.addSeries(pop5);
		dataset.addSeries(pop6);

		chart = ChartFactory.createTimeSeriesChart("Caractéristiques", "Date",
				"Valeur", dataset, true, true, false);
		XYPlot plot = chart.getXYPlot();
		DateAxis axis = (DateAxis) plot.getDomainAxis();
		plot.setBackgroundPaint(new Color(0xffffe0));
		plot.setDomainGridlinesVisible(true);
		plot.setDomainGridlinePaint(Color.lightGray);
		plot.setRangeGridlinesVisible(true);
		plot.setRangeGridlinePaint(Color.lightGray);
		plot.setDomainCrosshairVisible(true);
		plot.setRangeCrosshairVisible(false);
		final XYItemRenderer xyitemrenderer = plot.getRenderer();
		if (xyitemrenderer instanceof XYLineAndShapeRenderer) {
			final XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) xyitemrenderer;
			renderer.setBaseShapesFilled(true);
			renderer.setBaseShapesVisible(true);
			renderer.setShapesVisible(true);
			renderer.setDrawOutlines(true);
		}
		axis.setDateFormatOverride(new SimpleDateFormat("dd-MM-yy '\n' HH:mm"));

		System.err.println("fin chart");


		return SUCCESS;
	}

	public String afficherTest() {
		resultmanager = new ResultManager();
		List<Result> list = resultmanager.MesResultat(id);
		result = list.get(list.size() - 1);
		setMetric(metriquesmanager.list(id).get(0));
		setMetric(calcule.calculMetrique(metric, result));
		propriete = proprietemanager.list(id).get(0);
		propriete = calcule.calculPropriete(propriete);
		sub = subcarac.list(id).get(0);
		sub = calcule.calculSubcarac(sub);
		carac = caracteristiques.list(id).get(0);
		carac = calcule.calculCaracteristiques(carac);
		metric_fonct = carac.getFonctionnalite();
		metric_fiab = carac.getReliabilite();
		metric_util = carac.getUsabilite();
		metric_effic = carac.getEfficacite();
		metric_maint = carac.getMaintenabilite();
		metric_port = carac.getPortabilite();
		return SUCCESS;
	}

	public String testerJava() {
		System.out.println("-----------" + monjava);
		qdox.actionarbo(new File(monjava));
		qdox.metric(getId());

		setParametres(qdox.getParametres());
		setCarac(qdox.getCarac());
		setSub(qdox.getSub());
		setPropriete(qdox.getPropriete());

		metric_fonct = carac.getFonctionnalite();
		metric_fiab = carac.getReliabilite();
		metric_util = carac.getUsabilite();
		metric_effic = carac.getEfficacite();
		metric_maint = carac.getMaintenabilite();
		metric_port = carac.getPortabilite();
		System.out.println("");

		// mymetriques=qdox.getMymetriques();
		return SUCCESS;
	}

	public FileManager getProjet() {
		return projet;
	}

	public void setProjet(FileManager projet) {
		this.projet = projet;
	}

	public POFManager getManager() {
		return manager;
	}

	public void setManager(POFManager manager) {
		this.manager = manager;
	}

	public MyFile getMyFile() {
		return myFile;
	}

	public void setMyFile(MyFile myFile) {
		this.myFile = myFile;
	}

	public String getMonjava() {
		return monjava;
	}

	public void setMonjava(String monjava) {
		this.monjava = monjava;
	}

	public void rangePackages() {
		int j = 0;
		for (int i = 1; i < packages.size(); i++) {
			ArbProjectStructure pathPack = new ArbProjectStructure();
			System.out.println("test: " + packages.get(i).getJavaName()
					+ "avec: " + packages.get(j).getPackName());
			if (packages.get(i).getPackName()
					.equals(packages.get(j).getPackName())) {// same package
				packages.get(i).setPackName("0");
			} else {
				j = i;
				System.out.println("testooooooo");
			}
		}
	}

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public Metriques getParametres() {
		return parametres;
	}

	public void setParametres(Metriques parametres) {
		this.parametres = parametres;
	}

	public Caracteristiques getCarac() {
		return carac;
	}

	public void setCarac(Caracteristiques carac) {
		this.carac = carac;
	}

	public Subcarac getSub() {
		return sub;
	}

	public void setSub(Subcarac sub) {
		this.sub = sub;
	}

	public double getMetric_fonct() {
		return metric_fonct;
	}

	public void setMetric_fonct(double metric_fonct) {
		this.metric_fonct = metric_fonct;
	}

	public double getMetric_fiab() {
		return metric_fiab;
	}

	public void setMetric_fiab(double metric_fiab) {
		this.metric_fiab = metric_fiab;
	}

	public double getMetric_util() {
		return metric_util;
	}

	public void setMetric_util(double metric_util) {
		this.metric_util = metric_util;
	}

	public double getMetric_effic() {
		return metric_effic;
	}

	public void setMetric_effic(double metric_effic) {
		this.metric_effic = metric_effic;
	}

	public double getMetric_maint() {
		return metric_maint;
	}

	public void setMetric_maint(double metric_maint) {
		this.metric_maint = metric_maint;
	}

	public double getMetric_port() {
		return metric_port;
	}

	public void setMetric_port(double metric_port) {
		this.metric_port = metric_port;
	}

	public Propriete getPropriete() {
		return propriete;
	}

	public void setPropriete(Propriete propriete) {
		this.propriete = propriete;
	}

	public rapportManager getReportmanager() {
		return reportmanager;
	}

	public void setReportmanager(rapportManager reportmanager) {
		this.reportmanager = reportmanager;
	}

	public rapport getReport() {
		return report;
	}

	public void setReport(rapport report) {
		this.report = report;
	}

	public Calcule getCalcule() {
		return calcule;
	}

	public void setCalcule(Calcule calcule) {
		this.calcule = calcule;
	}

	public Metriques getMetric() {
		return metric;
	}

	public void setMetric(Metriques metric) {
		this.metric = metric;
	}

	public MetriquesManager getMetriquesmanager() {
		return metriquesmanager;
	}

	public void setMetriquesmanager(MetriquesManager metriquesmanager) {
		this.metriquesmanager = metriquesmanager;
	}

	public ProprieteManager getProprietemanager() {
		return proprietemanager;
	}

	public void setProprietemanager(ProprieteManager proprietemanager) {
		this.proprietemanager = proprietemanager;
	}

	public CaracteristiquesManager getCaracteristiques() {
		return caracteristiques;
	}

	public void setCaracteristiques(CaracteristiquesManager caracteristiques) {
		this.caracteristiques = caracteristiques;
	}

	public SubcaracManager getSubcarac() {
		return subcarac;
	}

	public void setSubcarac(SubcaracManager subcarac) {
		this.subcarac = subcarac;
	}

	public Stat getStat() {
		return stat;
	}

	public void setStat(Stat stat) {
		this.stat = stat;
	}
}